package coffee.tigase.auth;

import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.AuthorizeCallback;
import javax.security.sasl.RealmCallback;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;

public class AuthMain {

	/**
	 * 
	 * @param args
	 * 
	 * @throws SaslException
	 */

	public static void main(String[] args) throws SaslException {

		Map<String, String> props = new TreeMap<String, String>();

		SaslServer ss = Sasl.createSaslServer("PLAIN", "xmpp", "java.com",

		props, new ServerCallbackHandler());

		byte[] challenge = ss.evaluateResponse(new byte[0]);// 不懂为何要传入一个0长度的字符串

		SaslClient sc = Sasl.createSaslClient(new String[] { "PLAIN" },

		"11", "xmpp", "java.com", null, new ClientCallbackHandler());

		byte response[];

		if (challenge != null) {

			response = sc.evaluateChallenge(challenge);

		} else {

			response = sc.evaluateChallenge(null);

		}

		ss.evaluateResponse(response);

		if (ss.isComplete()) {

			System.out.println("auth success");

		}

	}

}

class ClientCallbackHandler implements CallbackHandler {

	public void handle(Callback[] callbacks) throws IOException,

	UnsupportedCallbackException {

		for (int i = 0; i < callbacks.length; i++) {

			if (callbacks[i] instanceof NameCallback) {

				NameCallback ncb = (NameCallback) callbacks[i];

				ncb.setName("11");

			} else if (callbacks[i] instanceof PasswordCallback) {

				PasswordCallback pcb = (PasswordCallback) callbacks[i];

				pcb.setPassword("admin1".toCharArray());

			} else if (callbacks[i] instanceof RealmCallback) {

				RealmCallback rcb = (RealmCallback) callbacks[i];

				rcb.setText("java.com");

			} else {

				throw new UnsupportedCallbackException(callbacks[i]);

			}

		}

	}

}

class ServerCallbackHandler implements CallbackHandler {

	public ServerCallbackHandler() {

	}

	public void handle(final Callback[] callbacks) throws IOException,

	UnsupportedCallbackException {

		for (Callback callback : callbacks) {

			if (callback instanceof RealmCallback) {

				// do your business

			} else if (callback instanceof NameCallback) {

				// do your business

			} else if (callback instanceof PasswordCallback) {

				((PasswordCallback) callback).setPassword("admin1"

				.toCharArray());

			} else if (callback instanceof AuthorizeCallback) {

				AuthorizeCallback authCallback = ((AuthorizeCallback) callback);

				authCallback.setAuthorized(true);

			} else {

				System.out.println(callback.getClass().getName());

				throw new UnsupportedCallbackException(callback,

				"Unrecognized Callback");

			}

		}

	}

}